package com.lyun.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyun.bo.GetAllSmallVideosBo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lyun.common.MyBusinessException;
import com.lyun.constants.RedisKeyConstants;
import com.lyun.dto.AdminAuditSmallVideoDTO;
import com.lyun.dto.AdminSmallVideoDTO;
import com.lyun.enums.SmallVideoEnum;
import com.lyun.mapper.SmallVideoMapper;
import com.lyun.pojo.SmallVideo;
import com.lyun.pojo.User;
import com.lyun.service.SmallVideoService;
import com.lyun.service.UserService;
import com.lyun.service.VideoConcernService;
import com.lyun.vo.AdminSmallVideoVO;
import com.lyun.vo.PageVO;
import com.lyun.vo.SmallVideosVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@DubboService
public class SmallVideoServiceImpl extends ServiceImpl<SmallVideoMapper, SmallVideo> implements SmallVideoService {

    @Resource
    private SmallVideoMapper smallVideoMapper;

    @Resource
    private VideoConcernService videoConcernService;

    @DubboReference
    private UserService userService;

    @Resource
    private RedisTemplate<String, Integer> redisTemplate;

    /**
     * @return
     */
    @Override
    public PageVO<SmallVideosVo> getAllSmallVideoList(GetAllSmallVideosBo bo) {
        //获取小视频列表
        LambdaQueryWrapper<SmallVideo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SmallVideo::getIsDelete, SmallVideoEnum.Delete.NORMAL);
        queryWrapper.orderByDesc(SmallVideo::getCreateTime);
        queryWrapper.eq(SmallVideo::getAuditStatus, 1);
        Page<SmallVideo> pageInfo = new Page<>(bo.getPage(), bo.getPageSize());
        smallVideoMapper.selectPage(pageInfo, queryWrapper);

        PageVO<SmallVideo> smallVideoPageVo = new PageVO<>(pageInfo);
        smallVideoPageVo.setPage(bo.getPage());
        smallVideoPageVo.setPageSize(bo.getPageSize());

        List<SmallVideo> smallVideoList = pageInfo.getRecords();

        PageVO<SmallVideosVo> pageVo = new PageVO<>();
        BeanUtils.copyProperties(smallVideoPageVo, pageVo, "items");

        if (CollectionUtils.isEmpty(smallVideoList)) {
            return pageVo;
        }

        //获取视频作者idList
        List<Long> authorIdList = smallVideoList.stream().map(SmallVideo::getUserId).distinct().collect(Collectors.toList());

        List<User> userList = userService.getListByIds(authorIdList);
        //Map<Long, List<User>> authorIdWithUserMap = userList.stream().collect(Collectors.groupingBy(User::getId));
        Map<Long, User> authorIdWithUserMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        Set<Long> set = videoConcernService.getVideoConcernByUserIdWithAuthorId(bo.getId(), authorIdList);

        boolean flag = Objects.nonNull(set);

        List<SmallVideosVo> voList = smallVideoList.stream().map(item -> {
            //基本属性赋值
            SmallVideosVo vo = new SmallVideosVo();
            BeanUtils.copyProperties(item, vo);
            vo.setId(item.getId().toString());
            vo.setCover(item.getVideoThumbnail());
            vo.setVideoUrl(item.getVideoFile());

            User author = authorIdWithUserMap.get(item.getUserId());
            vo.setAvatar(author.getHeader());
            vo.setNickname(author.getNickname());

            //查询是否关注该作者 以及是否点赞该视频
            if (flag) {
                vo.setHasFocus(set.contains(item.getUserId()) ? 1 : 0);
            } else {
                vo.setHasFocus(0);
            }

            vo.setHasLiked(1);

            //todo 试着引入本地缓存
            //计算点赞量、评论数
            vo.setLikeCount(redisTemplate.opsForValue().get(RedisKeyConstants.SMALL_VIDEO_LIKE_COUNT + item.getId()));
            vo.setCommentCount(redisTemplate.opsForValue().get(RedisKeyConstants.SMALL_VIDEO_COMMENT_COUNT + item.getId()));

            //todo 先这样随便填写一下
            vo.setLikeCount(0);
            vo.setCommentCount(0);
            return vo;
        }).collect(Collectors.toList());

        pageVo.setItems(voList);

        return pageVo;
    }

    @Override
    public PageVO<AdminSmallVideoVO> adminGetAll(AdminSmallVideoDTO dto) {
        Page<SmallVideo> page = new Page<>(dto.getPage(), dto.getPageSize());
        LambdaQueryWrapper<SmallVideo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dto.getAuditStatus() != null, SmallVideo::getAuditStatus, dto.getAuditStatus());
        queryWrapper.eq(SmallVideo::getIsDelete, 0);
        queryWrapper.orderByDesc(SmallVideo::getCreateTime);
        smallVideoMapper.selectPage(page, queryWrapper);
        List<SmallVideo> smallVideoList = page.getRecords();

        if (CollectionUtils.isEmpty(smallVideoList)) {
            return new PageVO<>();
        }

        List<Long> userIdList = smallVideoList.stream().map(SmallVideo::getUserId).collect(Collectors.toList());
        List<User> userList = userService.getListByIds(userIdList);
        Map<Long, String> userIdWithNameMap = userList.stream().collect(Collectors.toMap(User::getId, User::getNickname));

        List<AdminSmallVideoVO> voList = smallVideoList.stream().map(item -> {
            AdminSmallVideoVO vo = new AdminSmallVideoVO();
            BeanUtils.copyProperties(item, vo);
            vo.setId(item.getId().toString());
            vo.setUserId(item.getUserId().toString());
            if (userIdWithNameMap.containsKey(item.getUserId())) {
                vo.setUserName(userIdWithNameMap.get(item.getUserId()));
            }
            return vo;
        }).collect(Collectors.toList());

        PageVO<AdminSmallVideoVO> vo = new PageVO<>();
        vo.setCounts(page.getTotal());
        vo.setItems(voList);
        vo.setPageSize(dto.getPageSize());
        return vo;
    }

    /**
     * 审核小视频列表
     *
     * @param dto
     */
    @Override
    public void auditSmallVideo(AdminAuditSmallVideoDTO dto) {
        SmallVideo smallVideo = smallVideoMapper.selectById(Long.valueOf(dto.getSmallVideoId()));
        if (smallVideo == null) {
            throw new MyBusinessException("该小视频不存在");
        }
        smallVideo.setAuditStatus(dto.getStatus());
        smallVideoMapper.updateById(smallVideo);
    }

    /**
     * 根据id 给vo加上对应的参数 比如 hasLiked likeCount commentCount等等
     *
     * @param id 当前用户的id
     * @return
     */
    public List<SmallVideosVo> addParametersWithUserId(List<SmallVideosVo> smallVideosVos, Long id) {

        return smallVideosVos.stream().map((item) -> {
            item.setHasFocus(videoConcernService.getAlreadyConcernBySelfIdAndUserId(id, item.getUserId()) ? 1 : 0);
            item.setHasLiked(1);
            item.setLikeCount(888);
            item.setCommentCount(555);
            return item;
        }).collect(Collectors.toList());

    }
}
